package serveur;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.print.attribute.standard.Severity;

import Communication.Couple;
import Communication.InfosImage;
import Communication.InfosObjet;
import Communication.KryoConfiguration;
import Communication.ObjetsAProximite;
import Communication.ReponseIncarnationFantomeAcceptee;
import Communication.ChangerMouvement;
import Communication.RequeteIncarnerFantome;
import Communication.RequeteInfoImage;
import Communication.RequeteInfoObjet;

import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;

public class Modele {
	private Monde monde;
	private Map<Integer, Fantome> connectionVersfantome = new HashMap<>();
	private Server server;

	private static Couple p1 = new Couple(400,300);
	private static Couple p2;
	public Modele() {
		monde = new Monde();
		
		p2 = new Couple(monde.getHauteur()-400,monde.getLargeur()-300);
		
		Mur sol = new Mur(-10f, 0f, 1f, 10f);
		monde.ajouterObject2D(sol);

		monde.lancerMonde();

		server = new Server();
		
		KryoConfiguration.configurer(server.getKryo());
		
		System.out.println("Seveur: lancement");
		try {
			server.bind(54555, 54777);
			server.addListener(new ClientActionListener());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		new Thread(server).start();
		
		while (true) {

			if (monde.maj()) {
				for(Connection connection: server.getConnections()){
					int idConnection = connection.getID();
					Fantome fantome = connectionVersfantome.get(idConnection);
					if(fantome!=null){
						Couple centre = Math.ensureBox( fantome.getPosition(), p1, p2);
						Couple pa = Math.ensureBox(centre.moins(p1), p1, centre);
						Couple pb = Math.ensureBox(centre.plus(p1), centre, p2);
						
						List<Integer> listeObjets = monde.getIdObjetsToucheBox(new Box(pa,pb));
						Map<Integer,Couple> nouvellesPositions = new HashMap<>();
						for(int idObjets: listeObjets){
							Objet2D objet = monde.getObject2D(idObjets);
							nouvellesPositions.put(idObjets, objet.getPosition());
						}
						server.sendToTCP(idConnection, new ObjetsAProximite(listeObjets,nouvellesPositions,centre));
					}
					
				}
			}
			try {
				server.update(2000);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		

	}

	private class ClientActionListener extends Listener {
		public void received(Connection c, Object object) {
			int connectionID = c.getID();
			System.out.println("Requete Client:" + c.getID() + ":"
					+ object.getClass().getName());
			if (object instanceof RequeteIncarnerFantome) {

				Fantome fantome = monde.ajouterFantome();
				monde.ajouterFantome();
				connectionVersfantome.put(c.getID(), fantome);
				server.sendToTCP(connectionID,new ReponseIncarnationFantomeAcceptee(fantome.getId()));
				server.sendToTCP(connectionID, new InfosImage(0,"bouleBlanche.png"));
			} else if( object instanceof RequeteInfoObjet) {
				RequeteInfoObjet requeteInfoObjet = (RequeteInfoObjet) object;
				InfosObjet infosObjet = monde.getObject2D(requeteInfoObjet.id).getInfos();
				server.sendToTCP(connectionID, infosObjet);
			} else if ( object instanceof RequeteInfoImage) {
				RequeteInfoImage requeteInfoImage = (RequeteInfoImage) object;
				server.sendToTCP(connectionID, new InfosImage(requeteInfoImage.id,"bouleBlanche.png"));
			} else if (object instanceof ChangerMouvement){
				Fantome fantome = connectionVersfantome.get(connectionID);
				if(fantome!=null){
					ChangerMouvement requete = (ChangerMouvement) object;
					fantome.setMouvementHorizontal(requete.mouvementHorizontal);
					fantome.setMouvementVertical(requete.mouvementVertical);
				}
			}

		}
	}

	public static void main(String[] args) {
		new Modele();
	}

}
